home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-20 / nos_kit3.zip / TNC_TNC2.ZIP / TNC2BOOT.MAC < prev    next >
Text File  |  1987-05-26  |  6KB  |  261 lines

  1. ; KISS-TNC-HEX-LOADER.MAC -  KISS TNC Intel Hex Loader v0.3
  2. ; k3mc 8 Aug 86 v0.1
  3. ;      4 Oct 86 v0.2
  4. ;     18 Oct 86 v0.2a
  5. ;     18 Oct 86 v0.3
  6. ; v0.2 correctly sets the SP for either 16k or 32k of memory, and strips
  7. ; the parity bit from incoming chars.
  8. ; v0.2a allows 8k of RAM
  9. ; v0.3 try horrible hack to allow use w/o cutting JMP6
  10.  
  11.     .z80
  12.     aseg
  13.     org    4000h
  14.  
  15. RAM    equ    8000h        ;Where the RAM begins
  16.  
  17. ENQ    equ    5h
  18. ACK    equ    6h
  19. NAK    equ    15h
  20. colon    equ    ':'
  21.  
  22. rr_eof    equ    1        ;Record Type for End of File / begin execution
  23.  
  24.  
  25. ; SIO equates
  26.  
  27. SIO    equ    0dch        ;actually, only A5 is used for SIO -cs
  28.  
  29. A_dat    equ    SIO+0        ;Modem port
  30. A_ctl    equ    SIO+1        ;Modem port
  31.  
  32. B_dat    equ    SIO+2        ;user serial port
  33. B_ctl    equ    SIO+3        ;user serial port
  34.  
  35. RR0_RXR    equ    1        ;Receiver Char Avail bit
  36. RR0_TBE    equ    4        ;TX Buffer Empty bit
  37.  
  38.  
  39.  
  40. ;
  41. ; The general form of an Intel HEX record is as follows:
  42. ;
  43. ; :LLaaaaRRdddd..ddCC
  44. ;
  45. ; where LL is the number of bytes of data between RR and CC,
  46. ; not including RR or CC.
  47. ; aaaa is an address (see below),
  48. ; RR is a record type,
  49. ; dd are data bytes,
  50. ; and CC is a checksum, calculated as follows:
  51. ;   CC = - ( LL + aaaa + RR + dd + dd + ... ( modulo 256 ) )
  52. ; That is, adding all the bytes LL to CC (inclusive), you should get zero.
  53. ;
  54. ; These are the record types needed:
  55. ; RR = 00 record type = data. aaaa is the load address for the data.
  56. ; RR = 01 record type = end of file.
  57. ;  aaaa is the beginning execution address. LL is 00.
  58. ;  :00aaaa01CC
  59. ;  So, for example, if the start address is 8000, the last line of the file is
  60. ;  :008000017F
  61. ;
  62. ; In this implementation, trailing checksums are ignored; you don't even have
  63. ; to include them.
  64. ;-----------------------------------------------------------------------------
  65. start:
  66.     di            ;for this test, NO INTERRUPTS!
  67.  
  68. ; Figure out where top of stack is, set stack pointer.
  69. ; silly TNC-2 does not do complete address decoding for the RAMs if you are
  70. ; using only the two 8k x 8 chips.  Hack to figure out top of memory so we can
  71. ; set stack pointer.  This is REQUIRED by the KISS TNC.
  72. ; newer hack to see if we've only got 8k RAM (v0.2a)
  73.  
  74.     ld    a,(9fffh)    ;top of RAM if only 8K
  75.     cpl
  76.     ld    b,a
  77.     ld    (9fffh),a
  78.  
  79.     ld    a,(9fffh)
  80.     cp    b
  81.     jp    z,ok_8        ;we have at least 8k of RAM
  82.  
  83.     di
  84.     halt            ;else there is no RAM, so stop
  85.  
  86. ok_8:
  87.     ld    a,(0bfffh)
  88.     cpl
  89.     ld    b,a
  90.     ld    (0bfffh),a
  91.  
  92.     ld    a,(0bfffh)
  93.     cp    b
  94.     jp    z,ok_16        ;we have at least 16k of RAM
  95.  
  96.     ld    sp,0a000h
  97.     jp    stack_loaded    ;else we only have 8k of RAM
  98.  
  99.     jp    ok_16
  100.  
  101. ; NOTE!!!! This is a horrible hack to allow automatic detection
  102. ;of the fact that JMP6 on TNC-2 has not been cut. This causes an RST 7 to
  103. ; happen, which we trap and go through a normal boot sequence... I TOLD you it
  104. ; was a hack! v0.3
  105.  
  106.     org    4038h
  107.     jp    4000h        ;force a boot if jumper not cut
  108.  
  109. ok_16:
  110.     ld    a,55h        ;one value
  111.     ld    (0bfffh),a
  112.     ld    a,0aah
  113.     ld    (0ffffh),a    ;other value
  114.  
  115.     ld    a,(0bfffh)    ;get what should be 55h if 32k
  116.  
  117.     cp    55h        
  118.     ld    sp,0
  119.     jr    z,stack_loaded    ;if is 55h, then we've got 32 K, else 16 k
  120.  
  121.     ld    sp,0c000h    ;force stack value.
  122.  
  123. stack_loaded:
  124.  
  125. ;init SIO for async
  126.  
  127.     ld    b,nb        ;n bytes for init
  128.     ld    c,B_ctl        ;to B port
  129.     ld    hl,binit    ;with these bytes
  130.     otir            ;NOW!
  131.  
  132.     ld    a,5
  133.     out    (A_ctl),a    ;Ready WR5
  134.     ld    a,80h
  135.     out    (A_ctl),a    ;turn off STATUS LED
  136.  
  137. loop:
  138.     call    getchar        ;returns char into A reg
  139.     cp    ENQ        ;is it Control-E character?
  140.     jr    z,ENQCHR    ;yes, deal with it
  141.     cp    colon
  142.     jr    z,saw_colon    ;Go into Intel Hex download mode
  143.     call    putchar        ;if neither, just echo it
  144.     jr    loop
  145.  
  146. ENQCHR:
  147.     ld    hl,ENQ_string
  148. ENQ_loop:
  149.     ld    a,(hl)
  150.     or    a
  151.     jr    z,loop
  152.     call    putchar
  153.     inc    hl
  154.     jr    ENQ_loop
  155.  
  156. saw_colon:
  157.     call    rdbyte
  158.     ex    af,af'        ;save in other register set for a sec
  159.     call    rdbyte
  160.     ld    h,a
  161.     call    rdbyte
  162.     ld    l,a
  163.     call    rdbyte
  164.     cp    rr_eof        ;is it record type 1 (begin execution)?
  165.     jr    nz,data_record    ;no, it's just another data record
  166. ;else we give machine to downloaded program
  167.     jp    (hl)        ;and go do it!
  168.  
  169. data_record:
  170.     ex    af,af'        ;get length value back
  171.     ld    b,a        ;and ready loop index
  172. load_loop:
  173.     call    rdbyte
  174.     ld    (hl),a
  175.     inc    hl
  176.     djnz    load_loop    ;load 'em up!
  177.  
  178. ; Note, we ignore checksums completely
  179.  
  180. find_colon:
  181.     call    getchar
  182.     cp    colon
  183.     jr    nz,find_colon    ;spin for a colon 
  184.     jr    saw_colon    ;when we find colon, deal with next record
  185.  
  186. ;*** Reads 2 characters from SIO, converts them to binary, and returns value
  187. ;*** into A reg.  Disturbs no registers except AF.
  188. rdbyte:
  189.     push    bc
  190.     call    getchar
  191.     call    mk_binary
  192.     rlca
  193.     rlca
  194.     rlca
  195.     rlca
  196.     ld    b,a        ;save hi part
  197.     call    getchar
  198.     call    mk_binary
  199.     or    b        ;get hi + lo parts
  200.     pop    bc        ;be tidy
  201.     ret
  202.  
  203. ;*** Convert the ASCII character into Binary character (src & dest is A reg)
  204. mk_binary:
  205.     push    hl
  206.     push    de
  207.     call    makeUC        ;if anybody uses lower case, it's OK
  208.     sub    '0'        ;convert ASCII -> binary (sorta)
  209.     ld    d,0
  210.     ld    e,a
  211.     ld    hl,btable    ;base of translation table
  212.     add    hl,de        ;produce pointer into table
  213.     ld    a,(hl)        ;get corresponding binary
  214.     pop    de
  215.     pop    hl        ;cleanliness is next to Godliness
  216.     ret
  217.  
  218. btable:    defb    0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,0,0ah,0bh,0ch,0dh,0eh,0fh
  219.  
  220. ;*** If the character in A reg is lower case, this makes it upper case.
  221. makeUC:
  222.     cp    'a'
  223.     ret    c        ;if less than an 'a' we're done
  224.     cp    'z'+1
  225.     ret    nc        ;if > than 'z', not a letter, so we're done
  226.     and    5fh        ;else force to UPPER CASE
  227.     ret
  228.  
  229. ;*** Get a char from user TTY (Port B), no interrupt mode. Return it in A reg.
  230. getchar:
  231.     in    a,(B_ctl)
  232.     and    RR0_RXR
  233.     jr    z,getchar    ;wait for a character to be typed
  234.     in    a,(B_dat)
  235.     and    7fh        ;strip parity bit (Phil's suggestion)
  236.     ret
  237.  
  238.  
  239. ;*** Put a character to user TTY (Port B), no interrupts.  Char is in A reg.
  240. putchar:
  241.     push    af        ;we will need A
  242. ploop:
  243.     in    a,(B_ctl)
  244.     and    RR0_TBE
  245.     jr    z,ploop        ;Wait for Transmitter buffer to become empty
  246.  
  247.     pop    af
  248.     out    (B_dat),a
  249.     ret
  250.  
  251.  
  252.  
  253. binit:    defb    1ah,0,14h,44h,3,0c3h,5,0eeh,11h,0    ;magic SIO inits
  254. bi_end    equ    $
  255. nb    equ    bi_end-binit    ;Number of bytes in previous string
  256.  
  257. ENQ_string:
  258.     defb    "KISS/Raw TNC Intel Hex Loader v0.3 18 Oct 86",13,10,0
  259.  
  260.     end    start
  261.